<template>
  <div class="app-container">
    <!-- 过滤 -->
    <div class="filter-container">
      <el-input v-model="listQuery.productLineName" placeholder="生产线名称" style="width: 200px;" class="filter-item" />
      <el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleFilter">
        {{ $t('table.search') }}
      </el-button>
      <el-button class="filter-item" type="primary" icon="el-icon-refresh" @click="resetHandler">
        重置
      </el-button>
    </div>
    <div style="margin-bottom: 10px;">
      <el-button class="filter-item" type="primary" icon="el-icon-edit" @click="openDialog">
        添加
      </el-button>
    </div>

    <!-- 表格 -->
    <el-table :key="tableKey" v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%;">
      <el-table-column align="center" label="编号">
        <template slot-scope="{row}">
          {{ row.id }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="生产线名称">
        <template slot-scope="{row}">
          {{ row.productLineName }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="说明">
        <template slot-scope="{row}">
          {{ row.description }}
        </template>
      </el-table-column>
      <el-table-column align="center" label="操作">
        <template slot-scope="{row}">
          <el-button type="primary" icon="el-icon-edit" circle @click="openDialog(row)" />
          <el-button type="danger" icon="el-icon-delete" circle @click="openConfirm(row)" />
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页条 -->
    <pagination v-show="total > 0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.size" @pagination="getList" />

    <!-- 对话框 -->
    <el-dialog :title="dialogTitle" :visible.sync="dialogFormVisible">
      <el-form ref="form" :model="form" :rules="rules">
        <el-form-item v-if="form.id" label="编号" :label-width="formLabelWidth">
          <el-input v-model="form.id" placeholder="编号" :disabled="true" autocomplete="off" />
        </el-form-item>
        <el-form-item label="生产线名称" :label-width="formLabelWidth" prop="productLineName">
          <el-input v-model="form.productLineName" placeholder="请输入生产线名称" autocomplete="off" />
        </el-form-item>
        <el-form-item label="产品" :label-width="formLabelWidth">
          <el-input v-model="form.record.materialName" :disabled="true" placeholder="产品" autocomplete="off" />
          <el-button type="primary" @click="openRecordDialog">选择</el-button>
        </el-form-item>
        <el-form-item label="产品型号" :label-width="formLabelWidth">
          <el-input v-model="form.record.version" placeholder="产品型号" :disabled="true" autocomplete="off" />
        </el-form-item>
        <el-form-item label="产品规格" :label-width="formLabelWidth">
          <el-input v-model="form.record.standard" placeholder="产品规格" :disabled="true" autocomplete="off" />
        </el-form-item>
        <el-form-item label="描述" :label-width="formLabelWidth" prop="description">
          <el-input v-model="form.description" type="textarea" :rows="2" placeholder="请输入描述" />
        </el-form-item>

        <el-divider>
          <el-tooltip class="item" effect="dark" content="新增或删除设备信息后，要记得点击保存哦" placement="bottom">
            <div>设备明细信息</div>
          </el-tooltip>
        </el-divider>

        <div style="margin-bottom: 5px;">
          <el-dropdown trigger="click" @command="handleCommand">
            <el-button type="primary">
              添加<i class="el-icon-arrow-down el-icon--right" />
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item v-for="(item, index) in deviceData.list" :key="index" :command="item.id">
                {{ item.deviceName }}
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </div>
        <el-table :data="form.deviceList" border style="width: 100%">
          <el-table-column type="index" align="center" label="序号" />
          <el-table-column align="center" label="设备">
            <template slot-scope="{row}">
              {{ row.deviceName }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="编码">
            <template slot-scope="{row}">
              {{ row.encoding }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="型号">
            <template slot-scope="{row}">
              {{ row.deviceName }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="设备">
            <template slot-scope="{row}">
              {{ row.version }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="生产日期">
            <template slot-scope="{row}">
              {{ row.productionDate }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="生产批号">
            <template slot-scope="{row}">
              {{ row.batchNo }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="制造商">
            <template slot-scope="{row}">
              {{ row.maker }}
            </template>
          </el-table-column>
          <el-table-column align="center" label="操作">
            <template slot-scope="{$index}">
              <el-button type="danger" @click="removeDevice($index)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitForm('form')">确 定</el-button>
      </div>
    </el-dialog>

    <!-- 物料档案对话框 -->
    <el-dialog title="选择物料档案" :visible.sync="recordDialogVisible">
      <el-row>
        <el-col :span="4">
          <el-tree :data="recordData.treeData" :props="recordData.defaultProps" @node-click="handleRecordNodeClick" />
        </el-col>
        <el-col :span="20">
          <el-table :data="recordData.list">
            <el-table-column align="center" label="编号">
              <template slot-scope="{row}">
                {{ row.id }}
              </template>
            </el-table-column>
            <el-table-column align="center" label="物料编码">
              <template slot-scope="{row}">
                {{ row.materialEncoding }}
              </template>
            </el-table-column>
            <el-table-column align="center" label="物料名称">
              <template slot-scope="{row}">
                {{ row.materialName }}
              </template>
            </el-table-column>
            <el-table-column align="center" label="型号">
              <template slot-scope="{row}">
                {{ row.version }}
              </template>
            </el-table-column>
            <el-table-column align="center" label="规格">
              <template slot-scope="{row}">
                {{ row.standard }}
              </template>
            </el-table-column>
            <el-table-column align="center" label="单位">
              <template slot-scope="{row}">
                {{ row.unit }}
              </template>
            </el-table-column>
            <el-table-column align="center" label="单价">
              <template slot-scope="{row}">
                {{ row.price }}
              </template>
            </el-table-column>
            <el-table-column align="center" label="类型">
              <template slot-scope="{row}">
                <el-tag size="mini" :type="row.type === 1 ? 'info' : ''">
                  {{ row.type === 1 ? '原料' : '成品' }}
                </el-tag>
              </template>
            </el-table-column>
            <el-table-column align="center" label="备注">
              <template slot-scope="{row}">
                {{ row.remark }}
              </template>
            </el-table-column>
            <el-table-column align="center" label="操作" fixed="right">
              <template slot-scope="{row}">
                <!-- 对话框表单中的物料答案 和 对话框物料档案中的某一项一致，按钮便显示禁用 -->
                <el-button type="primary" :disabled="form.record.id === row.id" @click="chooseRecord(row)">选择</el-button>
              </template>
            </el-table-column>
          </el-table>
          <pagination v-show="recordData.total > 0" :total="recordData.total" :page.sync="recordData.listQuery.page" :limit.sync="recordData.listQuery.size" @pagination="getRecordList" />
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>
<script>
import Pagination from '@/components/Pagination'
import { fetchList, fetchOne, save, edit, remove } from '@/api/factory-modeling'
import { save as factoryDetailSave, remove as factoryDetailRemove } from '@/api/factory-detail'
import { fetchOne as recordFetchOne, fetchList as recordFetchList } from '@/api/material-record'
import { fetchListByIds, fetchList as deviceFetchList } from '@/api/device'
import { uniqueArr } from '@/utils/myUtils'
export default {
  name: 'FactoryModeling',
  components: { Pagination },
  data() {
    return {
      // 功能标题
      title: '工厂建模',
      tableKey: 0,
      listLoading: true,
      // 查询参数
      listQuery: {
        page: 1,
        size: 10,
        productLineName: ''
      },
      // 表格数据
      list: null,
      // 总数
      total: 0,
      // 对话框显示
      dialogFormVisible: false,
      // 对话框宽度
      formLabelWidth: '120px',
      // 表单
      form: {
        id: '',
        productLineName: '',
        description: '',
        record: {
          id: '',
          materialEncoding: '',
          materialName: '',
          version: '',
          standard: '',
          unit: '',
          price: '',
          type: 0,
          remark: '',
          categoryId: ''
        }, // 物料档案数据，也是产品
        deviceList: [], // 设备列表
        detailIds: [], // 明细id集合
        recordId: '' // 物料id
      },
      // 对话框标题
      dialogTitle: '',
      // 校验规则
      rules: {
        productLineName: [
          { required: true, message: '请输入生产线名称', trigger: 'blur' }
        ]
      },
      // 选择物料档案对话框是否显示
      recordDialogVisible: false,
      // 物料档案数据
      recordData: {
        // 查询参数
        listQuery: {
          page: 1,
          size: 10,
          type: undefined
        },
        // 总数
        total: 0,
        list: null,
        // 树形控件数据
        treeData: [
          {
            label: '分类',
            children: [
              {
                label: '零件',
                value: 1
              },
              {
                label: '成品',
                value: 0
              }
            ]
          }
        ],
        // 树形控件属性
        defaultProps: {
          children: 'children',
          label: 'label'
        }
      },
      /**
       * 设备信息数据
       * @type {Object}
       */
      deviceData: {
        // 查询参数
        listQuery: {
          page: 1,
          size: 100,
          type: undefined
        },
        list: null
      }
    }
  },
  created() {
    this.getList()
  },
  methods: {
    /**
     * 查询
     */
    handleFilter() {
      this.getList()
    },
    /**
     * 重置
     */
    resetHandler() {
      this.listQuery = {
        page: 1,
        size: 10,
        productLineName: ''
      }
    },
    /**
     * 获取列表
     */
    getList() {
      fetchList(this.listQuery).then(resp => {
        const { data } = resp
        this.total = data.total
        this.list = data.list
        this.handleIds(this.list)
      }).finally(() => {
        this.listLoading = false
      })
    },
    /**
     * 处理id数据
     * @param {Array} list 工厂建模列表
     */
    handleIds(list) {
      if (list.factoryDetailList !== []) {
        list.forEach(im => {
          const detailIds = [] // 明细id
          const recordIds = [] // 物料档案id
          const factoryIds = [] // 工厂建模id
          const deviceIds = [] // 设备id
          for (const item of im.factoryDetailList) {
            detailIds.push(item.id)
            deviceIds.push(item.deviceId)
            recordIds.push(item.recordId)
            factoryIds.push(item.factoryId)
          }
          // 去重赋值
          im.detailIds = uniqueArr(detailIds)
          im.recordIds = uniqueArr(recordIds)
          im.factoryIds = uniqueArr(factoryIds)
          im.deviceIds = uniqueArr(deviceIds)
        })
      }
      this.list = list
    },
    /**
     * 执行操作 修改和新增
     */
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          if (this.form.id) { // 有 id 就是执行修改，否则执行添加
            this.editHandler()
          } else {
            this.addHandler()
          }
        } else {
          return false
        }
      })
    },
    /**
     * 开启对话框
     * @param {*} row 行数据
     */
    async openDialog(row) {
      this.dialogFormVisible = true
      this.getDeviceList() // 获取设备列表信息
      // 开启对话框清空表单数据
      this.form = {
        id: '',
        productLineName: '',
        description: '',
        record: {
          id: '',
          materialEncoding: '',
          materialName: '',
          version: '',
          standard: '',
          unit: '',
          price: '',
          type: 0,
          remark: '',
          categoryId: ''
        }, // 物料档案，也是产品
        deviceList: [], // 设备列表
        detailIds: [], // 明细id集合
        recordId: '' // 物料id
      }
      // 清除 rules 原因: 不清除会导致，使用同一个对话框，上一次的规则校验提示还存在
      this.$nextTick(() => {
        this.$refs['form'].clearValidate()
      })
      // 修改
      if (row.id) {
        this.dialogTitle = `修改${this.title}`
        this.getOne(row)
      } else { // 新增
        this.dialogTitle = `添加${this.title}`
      }
    },
    /**
     * 回显数据
     * @param {*} row 行数据
     */
    async getOne(row) {
      const { data } = await fetchOne(row.id)
      const record = await this.getRecordOne(row)
      const deviceList = await this.getDevice(row)
      data.record = record
      data.deviceList = deviceList
      data.detailIds = row.detailIds
      this.form = data
    },
    /**
     * 获取工厂建模明细-设备信息
     * @param {*} row 行数据
     */
    async getDevice(row) {
      // 设备ids有数据，再去发送请求
      if (row.deviceIds.length > 0) {
        const { data } = await fetchListByIds(row.deviceIds)
        return data
      }
      console.log('没有设备明细信息')
      return []
    },
    /**
     * 获取工厂建模明细-物料档案信息
     * @param {*} row 行数据
     */
    async getRecordOne(row) {
      // 物料档案ids有数据，再去发送请求
      if (row.recordIds.length > 0) {
        // 取出第一个物料档案id，该数据一般只有一个，只需取出第一个即可
        const { data } = await recordFetchOne(row.recordIds[0])
        return data
      }
      return {
        id: '',
        materialEncoding: '',
        materialName: '',
        version: '',
        standard: '',
        unit: '',
        price: '',
        type: 0,
        remark: '',
        categoryId: ''
      }
    },
    /**
     * 添加
     */
    addHandler() {
      save(this.form).then(resp => {
        this.$notify({
          title: '成功',
          message: resp.msg,
          type: 'success',
          duration: 5000
        })
      }).finally(() => {
        this.dialogFormVisible = false
        this.getList()
      })
    },
    /**
     * 修改
     */
    editHandler() {
      edit(this.form).then(resp => {
        this.$notify({
          title: '成功',
          message: resp.msg,
          type: 'success',
          duration: 5000
        })
      }).finally(() => {
        this.dialogFormVisible = false
        this.getList()
      })
    },
    /**
     * 打开确认框
     * @param {*} row 行数据
     */
    openConfirm(row) {
      const id = row.id
      const detailIds = row.detailIds
      this.$confirm(`此操作将永久删除编号为 ${id} 的数据`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.deleteHandler({ factoryIds: [id], detailIds })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    /**
     * 删除
     * @param {*} data 参数
     */
    deleteHandler(data) {
      remove(data).then(resp => {
        this.$notify({
          title: '成功',
          message: resp.msg,
          type: 'success',
          duration: 5000
        })
      }).finally(() => {
        this.getList()
      })
    },
    /**
     * 打开选择物料对话框
     */
    openRecordDialog() {
      // 显示选择物料对话框
      this.recordDialogVisible = !this.recordDialogVisible
      this.getRecordList()
    },
    /**
     * 选择物料
     * @param {*} row 当前选中行的数据
     */
    chooseRecord(row) {
      // 赋值给表单中的 record
      this.form.record = row
      this.form.recordId = row.id
      // 关闭物料选择对话框
      this.recordDialogVisible = !this.recordDialogVisible
      this.$message({
        message: '物料选择成功',
        type: 'success'
      })
    },
    /**
     * 获取物料档案列表
     */
    getRecordList() {
      recordFetchList(this.recordData.listQuery).then(resp => {
        const { data } = resp
        this.recordData.list = data.list
        this.recordData.total = data.total
      })
    },
    /**
     * 点击tree节点触发
     * @param {*} data 所点击的数据
     */
    handleRecordNodeClick(data) {
      // 赋值
      this.recordData.listQuery.type = data.value
      this.getRecordList()
    },
    /**
     * 获取设备信息列表
     */
    getDeviceList() {
      deviceFetchList(this.deviceData.listQuery).then(resp => {
        const { data } = resp
        this.deviceData.list = data.list
      })
    },
    /**
     * 点击选中项，触发
     * @param {Number} id 设备id
     */
    handleCommand(id) {
      // 发送请求，进行添加明细信息
      // 需要传入 设备id
      factoryDetailSave({ deviceId: id }).then(resp => {
        const { data } = resp
        // 赋值
        this.form.deviceList.push(data.device)
        this.form.detailIds.push(data.detailId)
        this.$message({
          message: resp.msg,
          type: 'success'
        })
      }).finally(() => {
        this.getList()
      })
    },
    /**
     * 移除设备信息
     * @param {*} index 索引
     */
    removeDevice(index) {
      this.$confirm('确定删除该设备吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消'
      }).then(() => {
        factoryDetailRemove([this.form.detailIds[index]]).then(resp => {
          this.$message({
            message: resp.msg,
            type: 'success'
          })
        }).finally(() => {
          // 移除数组元素: 明细id集合、设备列表
          this.form.detailIds.splice(index, 1)
          this.form.deviceList.splice(index, 1)
          this.getList()
        })
      }).catch(action => {
        if (action === 'cancel') {
          this.$message({
            type: 'info',
            message: '取消删除'
          })
        }
      })
    }
  }
}
</script>
<style scoped></style>
